suxilong 发表于 2013-2-19 10:47:13

关于M25P系列flash 驱动问题 (VHDL)

最近在尝试用FPGA直接控制 M25P系列flash, 在opencode 找了个源代码,依葫芦画瓢写了一个!
读ID貌似已经没有问题了!!

但是 写操作 一直没能成功,用示波器量了一下sclk,发现自从添加了检测WIP (读忙操作)状态后,一直处于死循环~~~~
不知哪里出了错!!!!


目前附件是我用特权的uart代码(能力有限只能借鉴特权大哥的code) 和opencode 关于SPI 操作的代码合并调试的!

uart_to_spi:
串口发一个01 读取ID
发一个02读一个字节
发一个03 擦错扇区,然后写入“05” (默认数) 到芯片中
spi_ctrl:
相关的FSM 变换


求各位大侠 指导指导!!!!

suxilong 发表于 2013-2-21 09:52:37

2013-02-21_093251.jpg

suxilong 发表于 2013-2-21 09:53:56

附近为逻辑仿真图

tangkuan660 发表于 2013-2-19 11:15:00

在你的代码spi_ctrl.vhd中,没有发现WIP 这个状态,目前你的代码具体是停在哪个状态?完整的状态名称是什么?另外读数据你能正确读出不?

suxilong 发表于 2013-2-20 11:09:44

tangkuan660 发表于 2013-2-19 11:15 static/image/common/back.gif
在你的代码spi_ctrl.vhd中,没有发现WIP 这个状态,目前你的代码具体是停在哪个状态?完整的状态名称是什么 ...

WIP是IC中的 一个标志位! 我没写清楚!具体你看看 M25P16 IC datasheet中 关于 Status 寄存器的说明就有了!


spi-ctrl 中检测 IC 忙的 状态是在 Busycheck。   
写操作的时候 我用示波器量的 时候发现sclk一直在发信号!所以程序应该走死了,

但具体停在哪个地方我也不敢断定!!!


我用modelsim做逻辑仿真 的时候, 基本都是正常的,(当然我没办法仿真出ICd_in 脚实际输出的信号)这是最让我郁闷!

NJ8888 发表于 2013-2-20 11:33:00

简单办法是先用MCU的IO出信号看应答,然后用FPGA对比参照

suxilong 发表于 2013-2-20 16:33:40

NJ8888 发表于 2013-2-20 11:33 static/image/common/back.gif
简单办法是先用MCU的IO出信号看应答,然后用FPGA对比参照

Flash ic先前是用51写的驱动~~~ 是可以实现的!

现在用FPGA 写,其中状态机全部是按照 51程序来 走的!

至于 你说用MCU 的IO输出信号看应答。。。????

这个flashicstatus的WIP位写操作或擦除时都为1,空闲时是0。

现在的问题就是 fpga 操作的时候很快,需要 进行 “读忙” 操作,虽然我状态机 中有这样的操作,可实际上好像没有作用。。。。

以下就是状态机中体现读忙 的状态
                                when SE_WAIT1 =>
                                                next_state<= Tx_CMD_SE;
                                when Tx_CMD_SE =>
                                                if tx_bit_cnt< x"7" then
                                                        next_state<= Tx_CMD_SE;
                                                else
                                                        next_state<= SE_WAIT2;
                                                end if;
                                when SE_WAIT2 =>
                                                next_state<= TxADD_H;
                                -- add RD_Status and Busy_check state
                                when SE_WAIT3 =>
                                                next_state<= Tx_CMD_RDSR;
                                               
                                when Tx_CMD_RDSR =>
                                  if tx_bit_cnt< x"7" then
                                                        next_state <= Tx_CMD_RDSR;
                                                else
                                                        next_state <= RD_Status;
                                                end if;
                                       
                                               
                                when RD_Status =>
                                                if rx_bit_cnt< x"7" then
                                                        next_state <= RD_Status;       
                                                else
                                                        next_state <= RDSR_WAIT1;
                                                end if;
                                               
                                when RDSR_WAIT1 =>
                                                next_state <= Busy_check;
                                                 
                                when Busy_check =>
                                                if status = B"0000_0001" then
                                                        next_state <= Tx_CMD_RDSR;
                                                elsif Se_flag ='1'then
                                                                next_state <= SE_WREN_PP;--SE wait
                                                       else
                                                           next_state <= CLR_CMD;   --PP wait
                                                end if;

我附近中的代码 很多,其实大家只需要 看spi—ctrl和 uart-to-spi这两个就好了!!!
其他都是uart 的操作基本没有什么问题!

uart-to-spi   主要是提示串口输入什么数,spi 进行什么操作
spi-ctrl是操作flash的核心!!

现在的问题就是写不进数据!如果哪位大侠又用fpga 操作这种类型的 flash 芯片 大可不用看我的代码!(因为实在太乱了)直接指点一下具体这个flash 的状态机该如何写

suxilong 发表于 2013-2-21 09:52:20

上面代码中,我忽略了WREN 与SE 之间 CS需要拉高拉低一下!昨天将其改正(CS需要拉高拉低一下) 后,发现如果单独操作 SE, PP ,RDEN , RDID 都是可以的

但如果将SE 和PP 连起来 写,只要串口发一个数,就实行 SE然后进行PP 发现一直不成功!~~~~~~逻辑仿真如下 麻烦哪位大侠指导一下1!!

D:\共享\DD\march

philoman 发表于 2013-2-21 18:24:25

楼主第一次用FLASH吗?Flash执行写和擦除命令需要一段时间,应当查询状态、待执行完成之后才可以发送下一批命令

suxilong 发表于 2013-2-22 10:48:00

philoman 发表于 2013-2-21 18:24 static/image/common/back.gif
楼主第一次用FLASH吗?Flash执行写和擦除命令需要一段时间,应当查询状态、待执行完成之后才可以发送下一批 ...

是啊,第一次用 FPGA控制 FLASH!!!!


我知道 执行写和擦除需要等待一段时间!

我现在最大的问题就是想 将擦除和执行写 串起来 成为一个连贯的动作!!!!

意思是, 串口接收到一个 数,然后擦除接着执行写操作!!!

分开的时候没有问题,但是串起来的时候就有问题了!!!

我也在中间增加了查询状态的 操作,也可以读到 status   中WIP 有变化!!但是就是写不进数据!! 我执行写操作与擦除之间的代码如下!!
   when Busy_check =>
                                                if status(0) = ‘1’ then
                                                      next_state <= SE_WAIT3 ;
                                                elsif Se_flag ='1'then
                                                                next_state <= SE_WREN_PP;--SE wait
                                                         else
                                                         next_state <= CLR_CMD;   --PP wait
                                                end if;

suxilong 发表于 2013-2-22 14:12:00

感谢大伙的大力支持!!!

下午终于 有了突破性进展了~~~~!!!写操作与擦除可以串起来了~~~!!!!
为了感谢大家的指导 先共享最新的源代码。。。欢迎指教!!!

当然这个是很不成熟的程序,因为目前还有一个问题!!!就是执行完写操作后如果加上 查询状态就无法 成功!
所以目前 只有在SE与PP之间有查询状态的操作!!!

可实际应用中急需在 PP之后进行查询状态的操作,不然肯定会有跑死或是跑偏的 可能!!!!



suxilong 发表于 2013-2-25 09:12:30

请问 串口如何一下子接收四个字节呢???

suxilong 发表于 2013-2-26 10:33:09

每天进步一点点!!!!

今天继续更新UART 控制 SPI flash IC的代码 !!
如附近所示 ,现在 uart 发四个字节的 数据依次为CMD ,ADDR—L,ADDR—M,ADDR—H   
然后实现任意地址擦除和写 一个默认字节

另外追加了BE 的功能!

suxilong 发表于 2013-2-27 09:13:11

暂时先告一段落!!! 因为现在下一步 该如何完善需要视上层和底层的 需要!!!

不过等到时完全OK我会继续更新的!!!

suxilong 发表于 2013-3-6 13:44:49

我今天对 该程序进行了时序仿真 结果大失所望~~~不知道为什么 逻辑仿真与时序仿真相差甚远~~~~~
但程序下载到版上功能却是正确的~~~奇怪了~~~
页: [1]
查看完整版本: 关于M25P系列flash 驱动问题 (VHDL)