Nucleo-F411RE SPI速度が設定どおりにならない

Nucleo-F411REを使用していますが、SPI速度が設定値通りになりません。
2MHzに設定すると1.5MHzぐらい、1MHzで750KHzぐらい。
mbed-os5.15 (mbed2でも同じでした)

Tickerの時間も1%ほど微妙にずれており、こちらは外部水晶をつけてmbed_app.jsonに"clock_source"の設定を書いたら正確になったのですが、SPI速度は変わらずです。
何か設定が必要でしょうか?

Imayan_chanさん
SPIの周波数設定は、思ったほど自由度がありません。
これはSPIが元々同期式シリアルでマスタ側のSCLKに同期したデータ転送なので、極端な話ですが一ビット送るたびにクロックスピードが変化してもデータ転送が通常では正常動作することから考えて、デバイスの最高クロックスピードは順守する必要がありますが、それ以下で使用するなら目標値に合わなくても実動作では問題ないからでしょう。
F411REのスペックを調べると、システムクロック(SystemCoreClock)ら分周したPCLK1(SPI2,3)もしくはPCLK2(SPI1,4,5)が基準クロックとしてSPIモジュールに入力されます。
各SPIモジュールには、ボーレートコントロールに3ビットのレジスタがあり(実際にはSPI_CR1レジスタのBR[2-0]ビット)、そこで
000: fPCLK/2, 001: fPCLK/4, 010: fPCLK/8, 011: fPCLK/16, 100: fPCLK/32, 101: fPCLK/64, 110: fPCLK/128, 111: fPCLK/256
のみが設定可能なだけです。
ちなみにシステムクロックが最高100MHzの場合(Nucleo-F411REボード標準設定)には、PCLK1が50MHzでPCLK2が100MHzとなりますので、
SPI1,4,5では、50MHzから390kHzまでの設定ですが、指定された周波数より低くて一番近い値に設定されると思われます。
従って、今回の目標クロックにならない件は、STM32F411REの仕様に起因する避けられない問題と捉えるべきでしょう。
Imayan_chanさんのシステムクロック(SystemCoreClock)は、外部水晶にしたとのことなので、
printf(“SystemClock=%d[Hz]\r\n”, SystemCoreClock);
で周波数を確認するとSPIクロックとの関係を調査出来ると思われます。

いつもありがとうございます。
SystemClockは外部水晶or内部発振で変わらず96MHzでした。3bitの分周比の低いほうになっていることが確認できました。
ずっとKL25Zを使っていて、結構細かく設定できていたので気づきませんでした。データシートをよく読むということですね。
mbedで作っているとTargetハードを変えるだけで普通に動いてしまうので、MCUの機能違いを意識することなく使ってしまいます。
勉強になりました。

Mbedが目指した昔の目標が、Targetハードを変えるだけで普通に動くことだったはずですので、ハード仕様書を読まなくても本来は使い始められないといけないですね。
周波数設定関数が
void frequency(int hz = 1000000);
でなく
int frequency(int hz = 1000000);
で設定した周波数を教えてくれれば、Targetハードの違いなどをもう少し意識できると思いますが、現在の仕様では、それも無理です。
私も、SDカード制御でSPI速度が上がらず苦労して知りました。