我刚刚试图让
FPGA能够将新的配置数据写入其SPI FLASH PROM,我想通过分享我花了最长时间的一些技巧来节省人们所经历的一些痛苦
弄清楚。
我正在使用带有Numonyx SPI FLASH(M25PX16)的Spartan 6 FPGA。
在我的应用程序中,我们希望通过以太网更新固件。
FPGA通过以太网获取.mcs文件并使用SPI将其写入FLASH,然后重置以加载新固件。
FLASH文档中没有提到的一件事是,在写入数据时只能将1改为0。
在使用Page Program或双输入快速编程指令写入数据之前,必须执行擦除操作,将目标区域中的所有位设置为1。
请记住,任何更改FLASH数据的指令都需要先写入Write Enable指令。
我遇到了一些非常奇怪的行为,当我重新启动它时,FLASH会覆盖大部分为零的第一页数据。
这只发生在我使用FPGA将数据写入FLASH时 - 如果我使用Impact来编程FLASH,那么当我重新上电时它工作得很好。
在使用Impact编程后,我回读了FLASH中的数据,它似乎与我在FPGA中编写的数据相同。
我检查了块保护(状态寄存器中的TB,BP2,BP1和BP0)并将其清零 - Impact没有锁定数据。
我最终将Block Protect设置为锁定我写入后使用的FLASH区域中的数据,这使得FLASH在重启后不会覆盖第一页。
我仍然不知道是什么导致它首先发生,或者我做的与Impact不同,但使用Block Protect似乎已经修复了它。
如果有人对此更了解,我很乐意听到。
Ifyouwanttowritean.mcsfiledirectlytoFLASHasopposedtoadata-onlyformatlike.bin,you'llneedtostripoutthemetadata..mcsfileshaveashortlineatthebeginningandendthatwillneedtobestrippedout.Thereisashortlineevery4097linesthatwillalsoneedtobestrippedout.Thefirst9andlast2charactersofeachlinealsoneedtoberemoved。
可能值得快速总结一下这个东西的写保护,因为它很复杂,并且在文档中没有很好地规划。
锁定数据的方法有三种 - 块保护,锁定寄存器和硬件保护。块保护:锁定内存的大部分内容。
这是非易失性的,并且会在
电源循环后继续保持数据锁定。
块保护由状态寄存器中的上/下位和BP2,BP1和BP0位定义。
M25PX16数据表中的表3显示了它们如何用于保护存储器的不同部分。
请注意,您只能使用块保护来保护内存开头或末尾内存的单个连续区域。块保护在数据表中有时称为软件保护模式2(SPM2)。锁定电阻:每个
扇区有一个锁定寄存器,阻止修改该扇区。
锁定寄存器是易失性的,并在上电时复位为解锁状态。
每个锁定寄存器都包含一个扇区锁定位(b1),当设置为1时,它会阻止扇区的修改。它只能通过上电复位为0.每个锁定寄存器除扇区外还包含一个写锁定位(b0)。
锁定位。
置1时,写锁定位可防止扇区锁定位置1。
写锁定寄存器(WRLR)指令可以清除写锁定位,这将允许您使用第二个WRLR指令设置扇区锁定位。
锁存寄存器有时在数据表中称为软件保护模式1(SPM1)。硬件保护:当FLASH上的W / Vpp引脚被驱动为0并且状态寄存器写禁止(SRWD)时,硬件保护模式被使能
状态寄存器中的位设置为1.启用时,不能修改FLASH的内容,也不能修改状态寄存器。
请注意,如果W / Vpp引脚驱动为低电平,状态寄存器中的SRWD位不执行任何操作。
还有写使能(WREN)指令。
任何修改FLASH存储器或其寄存器内容的指令都必须先写入Write Enable。
写使能指令将状态寄存器的写使能锁存(WEL)位设置为1. WEL位由任何需要它的指令清零,因此需要在执行另一条需要的指令之前再次使用另一条WREN指令进行设置。
写入启用。
如果我还记得其他任何事情,我会特别难以找到一个简单的答案,我会发布它。
祝你好运!
以上来自于谷歌翻译
以下为原文
I've just been through hell trying to get an FPGA to be able to write new configura
tion data to its SPI FLASH PROM, and I want to save people some of the pain I went through by sharing a couple of the tricks it took me longest to figure out.
I'm using a Spartan 6 FPGA with a Numonyx SPI FLASH (M25PX16). In my application, we want to update the firmware over Ethernet. The FPGA gets an .mcs file over Ethernet and writes it to the FLASH using SPI, then resets to load the new firmware.
One thing that isn't mentioned in the FLASH documentation is that you can only change 1's to 0's when writing data. You have to perform an erase, which sets all the bits in the targeted area to 1's, before writing data using a Page Program or Dual Input Fast Program instruction. Keep in mind that any instruction that changes FLASH data requires a Write Enable instruction first.
I encountered some really odd behavior where the FLASH would overwrite the first page of data with mostly zeroes when I power cycled it. This only happened when I had written the data to the FLASH using the FPGA - if I used Impact to program the FLASH, it worked just fine when I power cycled. I read back the data in the FLASH after programming with Impact, and it seemed to be identical to the data I wrote in with the FPGA. I checked the Block Protect (TB, BP2, BP1, and BP0 in the Status Register) and it was zeroed out - Impact hadn't locked down the data that way. I eventually set the Block Protect to lock down the data in the area of the FLASH I was using after I'd written to it, and that kept the FLASH from overwriting the first page after power cycling. I still have no idea what caused it to happen in the first place, or what I was doing differently from Impact, but using Block Protect seems to have fixed it. If anyone knows more about this one, I'd love to hear about it.
If you want to write an .mcs file directly to FLASH as opposed to a data-only format like .bin, you'll need to strip out the metadata. .mcs files have a short line at the beginning and end that will need to be stripped out. There is a short line every 4097 lines that will also need to be stripped out. The first 9 and last 2 characters of each line also need to be removed.
It's probably worth a quick summary of the write protection on this thing, since it's complicated and not well laid out in the documentation. There are three ways to lock down data - Block Protect, Lock Registers, and Hardware Protect.
Block Protect:
Locks down a large section of the memory. This is non-volatile and will continue to keep data locked after a power cycle. Block Protect is defined by the Top/Bottom bit and BP2, BP1, and BP0 bits in the Status Register. Table 3 in the M25PX16 datasheet shows how they are used to protect different parts of the memory. Note that you can only protect a single contiguous area of the memory that is either at the beginning or end of the memory using Block Protect.
Block Protect is sometimes referred to as Software Protected Mode 2 (SPM2) in the datasheet.
Lock Resisters:
Each sector has a lock register that prevents modification to that sector. The lock registers are volatile and are reset to an unlocked state on powerup. Each lock register contains a Sector Lock Down bit (b1) which prevents modification of the sector when set to 1. It can only be reset to 0 by a powerup.
Each Lock Register contains a Write Lock bit (b0) in addition to the Sector Lock Down bit. When set to 1, the Write Lock bit prevents the Sector Lock Down bit from being set. The Write Lock bit can be cleared by a Write to Lock Register (WRLR) instruction, which will allow you to set the Sector Lock Down bit with a second WRLR instruction.
The Lock Registers are sometimes referred to as Software Protected Mode 1 (SPM1) in the datasheet.
Hardware Protect:
Hardware Protect mode is enabled when the W/Vpp pin on the FLASH is driven to 0, and the Status Register Write Disable (SRWD) bit in the Status Register is set to 1. When it is enabled, the contents of the FLASH cannot be modified and the Status Register cannot be modified. Note that the SRWD bit in the Status Register does nothing without the W/Vpp pin driven low.
There is also the Write Enable (WREN) instruction. Any instruction that modifies the contents of the FLASH memory or its registers must be preceeded by a Write Enable. The Write Enable instruction sets the Write Enable Latch (WEL) bit of the Status Register to 1. The WEL bit is cleared by any instruction that requires it, so you need to set it again with another WREN instruction before doing another instruction that needs a Write Enable.
If I remember anything else I had a particularly tough time finding a simple answer to, I'll post it. Good luck!
0