搜索
bottom↓
回复: 14

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

[复制链接]

出0入0汤圆

发表于 2013-2-19 10:47:13 | 显示全部楼层 |阅读模式
最近在尝试用FPGA直接控制 M25P系列flash  , 在opencode 找了个源代码,依葫芦画瓢写了一个!
读ID貌似已经没有问题了!!

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


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

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


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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2013-2-21 09:52:37 | 显示全部楼层

出0入0汤圆

 楼主| 发表于 2013-2-21 09:53:56 | 显示全部楼层
附近为逻辑仿真图

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-2-19 11:15:00 | 显示全部楼层
在你的代码spi_ctrl.vhd中,没有发现WIP 这个状态,目前你的代码具体是停在哪个状态?完整的状态名称是什么?另外读数据你能正确读出不?

出0入0汤圆

 楼主| 发表于 2013-2-20 11:09:44 | 显示全部楼层
tangkuan660 发表于 2013-2-19 11:15
在你的代码spi_ctrl.vhd中,没有发现WIP 这个状态,目前你的代码具体是停在哪个状态?完整的状态名称是什么 ...

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


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

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


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

出0入0汤圆

发表于 2013-2-20 11:33:00 | 显示全部楼层
简单办法是先用MCU的IO出信号看应答,然后用FPGA对比参照

出0入0汤圆

 楼主| 发表于 2013-2-20 16:33:40 | 显示全部楼层
NJ8888 发表于 2013-2-20 11:33
简单办法是先用MCU的IO出信号看应答,然后用FPGA对比参照

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

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

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

这个flash  ic  status  的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 的状态机该如何写

出0入0汤圆

 楼主| 发表于 2013-2-21 09:52:20 | 显示全部楼层
上面代码中,我忽略了WREN 与SE 之间 CS需要拉高拉低一下!  昨天  将其改正(CS需要拉高拉低一下) 后,发现如果单独操作 SE, PP ,RDEN , RDID 都是可以的

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

[img]D:\共享\DD\march[2013-02-21_093251.jpg/img]

出0入0汤圆

发表于 2013-2-21 18:24:25 | 显示全部楼层
楼主第一次用FLASH吗?Flash执行写和擦除命令需要一段时间,应当查询状态、待执行完成之后才可以发送下一批命令

出0入0汤圆

 楼主| 发表于 2013-2-22 10:48:00 | 显示全部楼层
philoman 发表于 2013-2-21 18:24
楼主第一次用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;

出0入0汤圆

 楼主| 发表于 2013-2-22 14:12:00 | 显示全部楼层
感谢大伙的大力支持!!!

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

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

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



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-2-25 09:12:30 | 显示全部楼层
请问 串口如何一下子接收四个字节呢???

出0入0汤圆

 楼主| 发表于 2013-2-26 10:33:09 | 显示全部楼层
每天进步一点点!!!!

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

另外追加了BE 的功能!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-2-27 09:13:11 | 显示全部楼层
暂时先告一段落!!! 因为现在下一步 该如何完善需要视上层和底层的 需要!!!

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

出0入0汤圆

 楼主| 发表于 2013-3-6 13:44:49 | 显示全部楼层
我今天对 该程序进行了时序仿真 结果大失所望~~~不知道为什么 逻辑仿真与时序仿真相差甚远~~~~~
但程序下载到版上功能却是正确的~~~奇怪了~~~

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 07:17

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表