硬汉嵌入式论坛

 找回密码
 立即注册
查看: 156|回复: 2
收起左侧

[STM32H7] 基于STM32H7B0的OSPI外扩PSRAM【ESP-PSRAM64H/APS6404L】的分享

[复制链接]

1

主题

10

回帖

18

积分

新手上路

积分
18
发表于 前天 10:17 | 显示全部楼层 |阅读模式
前言:

   1. stm32h7b0 stm32h7b3 的关系  类似   stm32h750 和 stm32h743。其实h7b0的flash是2MB的,手册上标的是128KB,我当2MB用了一段时间了,正常工作。

         https://www.st.com/en/microcontr ... /stm32h7a3-7b3.html
         https://www.st.com/en/microcontr ... 7b0-value-line.html

          1.png
          2.png
   2. 外扩psram 【ESP-PSRAM64H/APS6404L 乐鑫要么抄的后者,要么定制的,命令一模一样,代码无缝移植】必须是OSPI外设【参考手册写了是支持写模式的】,经过手册阅读和代码测试,stm32h743/h750 的 QSPI外设在内存映射模式下只能读,不能写,我测试了h743的驱动,psram写会直接触发死机,读无问题
   3. 外扩8MB的用途为:为网络发来的数据提供一个巨大的缓存,为gui等使用提供一个巨大的动态内存池,当前内置的1.4MB在后续开发中,可能不足了,这里预留该psram作为备份,以牺牲读写性能为代价,sdram带宽虽高,但要求更大的封装。
   4. ESP-PSRAM64H/APS6404L 都是8MB,3.3V供电的【都有1.8V的型号】。区别为 后者的读ID指令spi频率得<=33MHz,但是我实测按120MHz读取,也是OK的,也就是可以和乐鑫的底层驱动无缝移植,无须修改代码。
       3.png
      4.png


理解内存映射的本质
      44.png
       在以下3种模式中:
         间接模式:所有操作均通过OCTOSPI寄存器预设命令、地址、数据和传输参数。

         自动状态轮询模式:外部内存状态寄存器被定期读取,并且在标志位设置的情况下可以生成中断。此功能仅在常规命令协议中可用。
         内存映射模式:外部存储器被内存映射,系统将其视为内部存储器,支持读写操作。

      内存映射是让你可以当内部sram一样,配置好 sct分散加载文件后,就可以直接操作的,例如
        mem_addr = (__IO uint32_t*)(0x90000000); //OCTOSPI1 0x90000000 - 0x9FFFFFFF
        for (int i = 0; i < 4096; i++) {
             *mem_addr++ = 0x112233A5;  //这样就实现了将数据写入外部的psram,qspi外设自动按照初始化的配置,实现底层读写时序,对开发者是透明的。
       而普通模式就得类似这样了:
        psram_write(addr, 0x112233A5,4096); //内部按时序图实现 指令+地址+交替字节【无】+空指令【无】+数据,如下图
             7.png
       所谓的 交替字节是指,这次通信需要额外携带的参数【即附加信息】,像这个psram,没有。
       所谓的 空指令,就是空等多少个周期,例如要从psram里读数据,你告诉psram地址后,它得查找一会,得耗时一下吧,这时你只能等吧,否则读的数据就是错的。


参考资料:
    1. STM32H723 QSPI扩RAM离奇问题分享
    https://forum.anfulai.cn/forum.p ... &extra=page%3D1
    2. 贡献一个H723外扩串行RAM的例子
    https://forum.anfulai.cn/forum.php?mod=viewthread&tid=120719

关键技术点:
    QSPI的通信阶段
       看下面这个图,心里就有底如何编写qspi底层驱动了,每个指令一定要搞清各个阶段是否存在【这个对照存储芯片的指令时序图,就能知道各个参数怎么配置了,较为简单】,指令长度、数据长度等,OSPI外设对这个阶段,拆分的更细,所以结构体变量更多,需要细细品读,磨刀不误砍柴工。
    5.png
    QSPI的内存映射地址
    stm32h7b0具有两个ospi外设【支持8线存储芯片,容量最大256MB】,分别映射两个内存区域。
    6.png
    关于cache策略的配置参见参考链接2,按照作者的思路将 wt改成了Device模式【TEX=0,C=0,B=1,S=0】,这样就不用读的时候去调用cache的api确保数据一致了 。
      22.png
   以上 mcu的ospi外设、cache、psram时序图+命令集,驱动就手到擒来了。
   先给psram发进入qspi模式的0x35命令【spi模式下】,再配置 ospi外设的内存映射读和写模式【这里使用 0xEB和0x38两个指令】,分别的时序就ok了,然后就配置sct文件,就可以当普通sram对待了,就是速度慢了点(133MHz 四线,但sdram 可以16线、32线,带宽高多了)
    关于OSPI的DQS问题,笔者在参考链接1里进行了回复,这里不再重复,如果有错误,请多多指教,共同进步。     
    关于ospi的 refresh变量 的含义:就是该值代表了过多少个clk(refresh+1),就自动释放cs【在这驱动psram是cs拉高】,通过波形分析,这样对性能有影响,这里是对参考链接2,这里设置的说明。本例就将它设置为0,不会定时自动控制cs释放。

完整可用代码压缩包:
    demo给了个esp的2MB的psram demo【手上的是2mb的乐鑫和8mb的APS6404L,两颗芯片都测试ok】,8MB的改下宏和ospi里的size就行【21就是2MB,23就是8MB】
    psram_keil_stm32h7b0_proj.7z (15.7 MB, 下载次数: 18)
    有点疑问在于,通过逻辑分析仪抓包看波形,好像soft reset没起作用?我在复位后,再发退出qspi模式,才能正常读到id【或者重上电,第一次ok】,否则全是0,应该是我后面发的进入qspi模式的影响,复位没让芯片退出qspi模式导致读id失败【读id需要spi模式】。目前的代码仍然是可以正常内存映射读写的,至于后面的 sct修改,大家就可以按照sdram的写法[本质上是一样的],稍微补充下,就ok了,后面笔者再完善下驱动,把格式和代码搞规范点,再上传个正式点的,当前就是个试验品,测试ok就丢上来分享了。
    有问题欢迎提出和指导。


评分

参与人数 2金币 +120 收起 理由
YFS + 20
eric2013 + 100 很给力!

查看全部评分

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
119429
QQ
发表于 前天 10:34 | 显示全部楼层
谢谢楼主分享,非常详细
回复

使用道具 举报

1

主题

11

回帖

14

积分

新手上路

积分
14
发表于 昨天 16:40 | 显示全部楼层
楼主牛掰 写的这么详细
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-11-21 23:07 , Processed in 0.040414 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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