2024年11月12日火曜日

STM32 RAMが足りねぇ→PSRAM→OCTOSPI

STM32H723Zの搭載RAM 500kBでは足りないんですよね.

しかもベタで500kBが在るのではなく、320kB、128kB、64kBなどと分割されていて、アクセスに支障があります.CPUは王様なのでアクセス自由ですけど、DMAは自己空間のRAMにしかアクセスできないのでDMAが自由に使えるのは320kBだけという制限がかかっていて尚更痛い.

そこで外部メモリの増設を考えます.
FMCというもので増設できるのですが、FMCの仕様はwide bus幅向けでなんかピンとこない.わたしが増設したいのはこんなものなのでFMCに接続できる気がしません.
どうやらOCTOSPIというSPI系peripheralで接続すると、FMCライクにメモリマップドで使えるみたいよ.というわけでOCTOSPIを使ってみよう.

ーーーー
いかん、ぜんぜんわからん!
STM32CubeMXでOCTOSPIの設定をするとこんな風にGPIOがアサインされます.
恐らくは、PSRAMの各pinに対応しているのでしょう.
接続してmemory mapped modeだとこのアドレスにmapされるらしい.OCTOSPI1とOCTOSPI2の2portあります.
ここから先がわからんちん!

ーーーー
話題は逸れますが、PSRAMは通常の2線SPIとしても、4線SPI(quad SPI)としても動かせます.2線4線の切り替えはどうやるのでしょうか?
datasheetにこんな絵がありました.起動時は2線SPIで動いていて、35Hコマンドを送信すると4線に移行するようです.ふむ~
出来るのかどうか知りませんが、2線SPIでmemory mapped modeで動かしてみたくなりました.
STM32H723Zのアサインはこうです.

ーーーー
SYM32CubeMXの設定

参考になる資料を見つけました、AN5050です.これの53ページにある表に着目.
 Table 8. STM32CubeMX - Configuration of OCTOSPI parameters

同表の右端の「QuadSPI PSRAM AP memory APS1604M」が目的物に近いです.いまわたしが取り付けようとしているのは「ESP-PSRAM64」ですので、64Mbitです.同表の物は16Mbitです.

表の各項目が、STM32CubeMXのOCTOSPI設定に対応していますので上から順に見てゆきましょう.
 Memory Type = Micron  言われるママ
 Device Size = 23  8Mbytesなら23だそうです   2^23=8M
 chip select high time = 2  clockの倍数 datasheetにそれっぽい項目が見つからず
 clock prescaler = 3  原発275MHzだと÷2だとギリかな、なので÷3にしとこ
 sample shift = half cycle   言われるママ
 delay hold quarter cycle = disable   言われるママ
 CS boundary = 0  言われるママ
 Delay Block = enable  言われるママ
 Reflesh rate = 2000  下記

Reflesh rateについて.
「ESP-PSRAM64」datasheetに「CE# low pulse width 8 μs max」というのがあります.あまり長い間CEにしておくとrefreshに入れなくて情報喪失しちゃうからmax 8uSな、という制約だと思います.
原発275MHzなので8uSecは2200clkです.少し余裕を見て2000clkでrefreshさせたいと思いました.

とりあえずSTM32CubeMXで設定する場所はこんなところかな.あとは割り込みのセットはするでしょう.MDMA設定はなんだかよく判らない.

判らないことが多過ぎる.

ーーーー
AN5050にsource codeが書かれていますのでそれに倣って実装しました.
しかし、うごかない
2線SPIと4線SPIを試してみたけど、アドレス0x90000000を一歩でも踏むとmemory faultが発生して死亡.地雷原だねぇ.
ロジアナの出番だが持ってないしロジアナ嫌い~

ーーーー
化けまくってるけど動き始めた.memory faultを出さなくするにはCPU settingをいじらなくちゃいけないのでした.0x9000000界隈のmemory access許可をします.
なにせPSRAMがmemory mappedですので、
 uint8_t* ptr = 0x90000000;
 *ptr = 123;
みたくフツーに読み書きできますのでナイスです.(化けてるけど)

ーーーー
化けが治りません.timing系ではなくsystem系トラブルです.
FAST READがしくじってるっぽいんだけど、これはもうロジアナだね.
アクセス境界に関連するhardware的なbugがあるとも言われ、撤退します.
PSRAMが動かないとなると、、、FMCか?

ーーーー
アクセス境界に少し関連するかもなのだけれど、PSRAM領域のアクセス自由度を「strongly ordered」にしておけというのがあります.これとかこれとか
これに望みを託す.
ところがSTM32CubeIDEの環境の中でどこをいじったら良いのかさっぱり判りませんでした.
「ARM_MPU_ACCESS_ORDERED」でproject内を検索するとこれが引っ掛かります.すなわち、TEX,share,cach,bufの4つのparameterを設定すればstrogly orderedになると言ってるんです.でもどこで設定すればいいのか判らない.
/**
* MPU Memory Access Attribute for strongly ordered memory.
*  - TEX: 000b     000
*  - Shareable     1
*  - Non-cacheable   0
*  - Non-bufferable   0
*/ 
#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U)
さらに徘徊しましたら特定できました.
灯台下暗し、main.cのMPU_Config()がそれです.STM32CubeMXのCPU設定のpramがここに反映されています.重要な4つを抜き出します.
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; 000
  MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE; 1
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; 0
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; 0
なんということでしょう.すでにstrongly orderedに設定済なのでした.それでも化けている.治らない.なんてこった.


あでゅ~

2 件のコメント:

  1. 読者
    なんかあったときの英語サイト(英語はぐぐる翻訳)くらいしか思いつかない

    返信削除